﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Basler.Pylon;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Threading;

namespace ETC.DLEDPositionTool.Helpers
{
    public class BaslerCamcs
    {
        public int CameraNumber = CameraFinder.Enumerate().Count;
        List<ICameraInfo> allCameras = null;//创建ICameraInfo对象的列表，用于保存遍历到的所有相机信息
        //委托+事件=回调函数，用于传递相机抓取的图像
        public delegate void CameraImage(Bitmap bmp);
        public event CameraImage CameraImageEvent;

        //放出一个Camera
        Camera camera;

        //basler里将相机采集到的图像转换成位图
        PixelDataConverter pxConvert = new PixelDataConverter();

        //控制相机采集图片的过程！
        bool Graber = true;

        IGrabResult grabResult;
        //第一步初始化相机  所用的全是camera里的事件然后绑定自己写好的事件
        public void CameraInit()
        {
            //相当于初始化了一下相机的动态链接库 可以调用Camera里面的东西了
            camera = new Camera();

            //自由连接模式     
            //当连接到相机时自动应用此配置
            //打开后，将其添加到Basler.Pylon.ICamera中。在打电话之前，摄像头打开了活动
            camera.CameraOpened += Configuration.AcquireContinuous;
            
            
            //断开连接事件
            camera.ConnectionLost += Camera_ConnectionLost;

            //抓取开始事件
            camera.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted;

            //抓取图片事件
            camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed;

            //抓取结束事件
            camera.StreamGrabber.GrabStopped += StreamGrabber_GrabStopped;
            //打开相机
            //StreamGrabber_GrabStarted
            //StreamGrabber_GrabStopped
            camera.Open();
        }

        public int CameraInit(string sn)
        {
            //相当于初始化了一下相机的动态链接库 可以调用Camera里面的东西了
            camera = new Camera();

            //自由连接模式     
            //当连接到相机时自动应用此配置
            //打开后，将其添加到Basler.Pylon.ICamera中。在打电话之前，摄像头打开了活动
            camera.CameraOpened += Configuration.AcquireContinuous;


            //断开连接事件
            camera.ConnectionLost += Camera_ConnectionLost;

            //抓取开始事件
            camera.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted;

            //抓取图片事件
            camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed;

            //抓取结束事件
            camera.StreamGrabber.GrabStopped += StreamGrabber_GrabStopped;
            //打开相机
            //StreamGrabber_GrabStarted
            //StreamGrabber_GrabStopped
            //camera.Open();

            string m_SerialNumber = "";//接收设备返回的序列号
            allCameras = CameraFinder.Enumerate();//获取所有相机设备
            for (int i = 0; i < allCameras.Count; i++)
            {
                try
                {
                    if (allCameras[i][CameraInfoKey.SerialNumber] == sn)
                    {
                        //如果当前相机信息中序列号是指定的序列号，则实例化相机类
                        camera = new Camera(allCameras[i]);
                        camera.Open();//打开相机
                        return 0;
                    }
                    continue;
                }
                catch
                {
                    return -1;
                }
            }
            return -1;
        }
        /// <summary>
        /// 停止抓取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StreamGrabber_GrabStopped(object sender, GrabStopEventArgs e)
        {
            Graber = false;
        }

        /// <summary>
        /// 抓取图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e)
        {
            grabResult = e.GrabResult;
            if (grabResult.IsValid)
            {
                if (Graber)
                {
                    //委托就用到了！
                    CameraImageEvent(GrabResult2Bmp(grabResult));
                }
            }

        }

        public Bitmap GetOneBitmapImage()
        {

            IGrabResult grabResult1 = grabResult;
            Thread.Sleep(100);
            if (grabResult1.IsValid)
            {
                if (Graber)
                {
                    return GrabResult2Bmp(grabResult1);
                }
            }
            return null;
        }

        /// <summary>
        /// 开始抓取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StreamGrabber_GrabStarted(object sender, EventArgs e)
        {
            Graber = true;
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Camera_ConnectionLost(object sender, EventArgs e)
        {
            try
            {
                //停止连接
                camera.StreamGrabber.Stop();
                //释放相机资源
                DestroyCamera();
            }
            catch (Exception)
            {
                return;
            }

        }

        /// <summary>
        /// 释放相机
        /// </summary>
        public void DestroyCamera()
        {
            if (camera != null)
            {
                camera.Close();
                camera.Dispose();
                camera = null;
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 将相机转换成图像转成Bitmap
        /// </summary>
        /// <param name="grabResult"></param>
        /// <returns></returns>
        Bitmap GrabResult2Bmp(IGrabResult grabResult)
        {
            //   PixelFormat   format:新的像素格式 System.Drawing.Bitmap。 这必须指定一个值，开头 Format。(参1:图宽，参2:图高，参3:像素格式)
            Bitmap b = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppArgb);

            //BitmapData:指定位图像的属性
            BitmapData bitmapData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
            //PixelType.BGRA8packed:抓取结果返回像素类型，由图像处理支持类使用
            pxConvert.OutputPixelFormat = PixelType.BGRA8packed;
            IntPtr bmpIntpr = bitmapData.Scan0;
            pxConvert.Convert(bmpIntpr, bitmapData.Stride * b.Height, grabResult);
            b.UnlockBits(bitmapData);
            return b;
        }


        public void OneShot()
        {
            if (Graber)
            {
                //PLCamera:所有可用于basler摄像机设备dByStre的参数名称列表  SingleFrame：启用单帧采集模式。
                camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);

                camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);

            }
        }

        public void KeepShot()
        {
            //Continuous：启用连续采集模式。
            camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
            //GrabStrategy.OneByOne:默认的抓取策略
            //GrabLoop.ProvidedByStreamGrabber:定义了额外线程的使用
            camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
        }

        public void Stop()
        {
            if (camera != null)
            {
                //流抓取停止
                camera.StreamGrabber.Stop();
            }
            else
            {
                MessageBox.Show("该相机已停止抓取");
            }
        }


        public int setExposureTime(long ExposureTimeNum)//设置曝光时间us
        {
            try
            {
                camera.Parameters[PLCamera.ExposureTimeAbs].SetValue(ExposureTimeNum);
            }
            catch
            {
                return -1;
            }
            return 0;
        }

        public int setGainRaw(long GainRawNum)//设置增益大小
        {
            try
            {
                camera.Parameters[PLCamera.GainRaw].SetValue(GainRawNum);
            }
            catch
            {
                return -1;
            }
            return 0;
        }

        public int pixelFormat(uint pixelType)//设置图像格式
        {
            //1：Mono8 2：彩色YUV422
            try
            {
                if (pixelType == 1)
                {
                    camera.Parameters[PLCamera.PixelFormat].TrySetValue(PLCamera.PixelFormat.Mono8);
                }
                else if (pixelType == 2)
                {
                    camera.Parameters[PLCamera.PixelFormat].TrySetValue(PLCamera.PixelFormat.YUV422Packed);
                }
            }
            catch
            {
                return -1;
            }
            return 0;
        }

       

        public int setOffsetX(long offsetX)//设置图像水平偏移
        {
            try
            {
                if (camera.Parameters[PLCamera.OffsetX].TrySetValue(offsetX))
                    return 0;
                else
                    return -1;
            }
            catch
            {
                return -1;
            }
        }

        public int setOffsetY(long offsetY)//设置图像竖直偏移
        {
            try
            {
                if (camera.Parameters[PLCamera.OffsetY].TrySetValue(offsetY))
                    return 0;
                else
                    return -1;
            }
            catch
            {
                return -1;
            }
        }

        public int setTriggerMode(uint TriggerModeNum)//设置触发模式
        {
            //1:为On 触发模式
            //0:Off 触发模式
            try
            {
                if (camera.Parameters[PLCamera.TriggerMode].TrySetValue(TriggerModeNum == 1 ? "On" : "Off"))
                    return 0;
                else
                    return -1;
            }
            catch
            {
                return -1;
            }
        }

        public int closeBalanceAuto()//关闭自动白平衡
        {
            try
            {
                camera.Parameters[PLCamera.BalanceWhiteAuto].TrySetValue("Off");
                
            }
            catch
            {
                return -1;
            }
            return 0;
        }

        public int setTriggerSource(uint TriggerSourceNum)//设置触发源
        {
            //直接改为软触发，此处已经写死
            try
            {
                if (camera.Parameters[PLCamera.TriggerSource].TrySetValue("Software"))
                    return 0;
                else
                    return -1;
            }
            catch
            {
                return -1;
            }
        }

        private Boolean IsMonoData(IGrabResult iGrabResult)//判断图像是否为黑白格式
        {
            switch (iGrabResult.PixelTypeValue)
            {
                case PixelType.Mono1packed:
                case PixelType.Mono2packed:
                case PixelType.Mono4packed:
                case PixelType.Mono8:
                case PixelType.Mono8signed:
                case PixelType.Mono10:
                case PixelType.Mono10p:
                case PixelType.Mono10packed:
                case PixelType.Mono12:
                case PixelType.Mono12p:
                case PixelType.Mono12packed:
                case PixelType.Mono16:
                    return true;
                default:
                    return false;
            }
        }

    }
}
